type OnExitHandler = () => void | Promise<void>;

// 是否已经处理退出
let isCalled = false;
let callback: OnExitHandler | undefined;
let waitToExit = 500;

async function doExit() {
  if (isCalled) return;
  isCalled = true;

  // 启动强制退出定时器
  const forceExitTimer = setTimeout(() => {
    process.exit(1);
  }, waitToExit);

  if (callback) {
    await Promise.resolve(callback());
  }
  // 停止强制退出定时器
  clearTimeout(forceExitTimer);
  // 退出进程
  process.exit(0);
}

/**
 * 注册程序退出时的清理回调函数
 *
 * 该函数允许注册一个在进程退出时执行的回调函数，
 * 并可以设置强制退出的等待的时间，用于强制退出
 *
 * @param cleanup - 退出时执行的回调函数，可以是同步或异步函数
 * @param wait - 退出前等待的时间（毫秒），默认为500ms
 */
export function onExit(cleanup?: OnExitHandler, wait?: number) {
  if (cleanup && !callback) {
    callback = cleanup;
  }
  if (wait) {
    waitToExit = wait;
  }

  // 注册退出事件监听器
  if (callback) {
    process.once("beforeExit", doExit);
    process.once("exit", doExit);
    process.once("SIGINT", doExit);
    process.once("SIGTERM", doExit);
    process.once("message", (message) => {
      if (message === "shutdown") {
        doExit();
      }
    });
  }
}

/**
 * 由于 Process.exit() 退出时，无法执行 async 函数；所以使用这个函数替换 Process.exit() 以进行优雅退出
 */
export function exit() {
  doExit();
}
